#!/usr/bin/env python -tt
# -*- coding: utf-8 -*-
# Autor: Pedro Moreira, 10015
# Data: 2011/11/30

import time
import sqlite3
from   BeautifulSoup import BeautifulSoup
import urllib2
import SimpleHTTPServer
import SocketServer
from   sets import Set
from pylab import *


class Teacher:
    '''
    Class para tratar dados estatísticos relativos a
    professores do Ensino Superior de Portugal
    links:
        http://bayes.colorado.edu/PythonIdioms.html
        http://code.google.com/edu/languages/google-python-class/
    '''

    def __init__(self):
        '''
        inicializa a classe e cria os dicionarios e sets a partir da bd
        '''
        # ao iniciar a classe são seleccionados todos os registos da base de
        # dados é criado uma lista de dicionarios 
        # cada elemento dos dicionários é um Set onde serão guardados os ids
        # dos respectivos professores evitando duplicados
        print "fetching data"
        allRows = self.__getFromDB__('''SELECT id, nome, grau, curso,
                                        categoria, regime, ano, tipo_estabelecimento,
                                        nome_estabelecimento from teachers''')
        # iniciar os dicionarios
        self.__graus, self.__cursos, self.__categorias = {},{},{}
        self.__regimes, self.__anos, self.__tiposEst = {},{},{}
        self.__estabelecimentos, self.__teachers = {},{}

        # criar uma lista com todos os dicionarios
        self.__dicts = [ self.__graus, self.__cursos, self.__categorias,
                         self.__regimes, self.__anos, self.__tiposEst,
                         self.__estabelecimentos, self.__teachers ]
        print "building data structures"
        for row in allRows: # percorrer todos os registos
            self.__dicts[7][row[0]] = row[1] # relacionar o professor id/nome
                                             # os duplicados são substituidos
            for i in range(2,9): # para as colunas 2 a 8 do registo
                if row[i] in self.__dicts[i-2]: # se o valor estiver já nas keys 
                    self.__dicts[i-2][row[i]].add(row[0]) # adiciona o id do
                                                         # professor ao Set
                else:
                    self.__dicts[i-2][row[i]] = Set() # cria o key
                    self.__dicts[i-2][row[i]].add(row[0]) # adiciona o id do
                                                          # prodessor ao ser
                pass #endif
            pass #end for in range(2,9)
        pass #end for in allRows
        # END __init__

    def getTotals(self, value1, value2, value3, ordered):
        
        if ordered == 0 and value1 != '' and value2 != '':
            return self.__dicts[6][value1] & self.__dicts[4][value2]
        elif ordered == 1 and value1 != '' and value2 != '' and value3 != '':
            #2,6,4
            a = self.__dicts[2][value1] & self.__dicts[6][value2]
            return a & self.__dicts[4][value3]
            
        elif ordered == 2 and value1 != '' and value2 != '' and value3 != '':
            #0,6,4
            a = self.__dicts[0][value1] & self.__dicts[6][value2]
            return a & self.__dicts[4][value3]
        else:
            return ""
        

    def getField(self, field):
        '''
        0->graus, 1->cursos, 2->categorias
        3->regimes, 4->anos, 5->tipos de estabelecimento
        6->nomes de estabelecimentos 7->professores
        '''
        return self.__dicts[field]
                                      
    def getByValue(self, field, value):
        '''
        0->graus, 1->cursos, 2->categorias
        3->regimes, 4->anos, 5->tipos de estabelecimento
        6->nomes de estabelecimentos 7->professores
        '''
        if value in self.__dicts[field]: #se a chave existir no respectivo field
            return self.__dicts[field][value] #devolve o set de professores
        return ([]) #senao devolve um set vazio 
    
    def getTeachers(self, lst):
        tchrs = {}
        for s in lst:
            tchrs[s] = self.__teachers[s].encode("utf-8")
        return tchrs

    def drawGraph(self, ys, labels, title, args):
        '''
        desenhar um gráfico dados os valores ys nos anos disponíveis na bd
        '''
        # http://matplotlib.sourceforge.net/examples/pylab_examples/vertical_ticklabels.html
        # http://www.secnetix.de/olli/Python/lambda_functions.hawk
        # http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.suptitle
        a = lambda:range(1, len(ys) + 1)
        plot(a(), ys)
        locs, labels = xticks(a(), self.__anos)
        setp(labels, 'rotation', 'vertical')
        suptitle(title, fontsize=20)
        show()
        pass

    def __getFromDB__(self, query):
        '''
        obter dados da DB
        '''
        try:
            self.__connection = sqlite3.connect("teachers.db")
        except:
            return "ERROR READING DATABASE"
        self.__c = self.__connection.cursor()
        self.__c.execute(query)
        self.__connection.commit()
        a = self.__c.fetchall()
        self.__connection.close()
        return a
    # END OF __getFromDB__()
    
    pass
# END OF CLASS Teachers


class Soup:
    '''
    Obter a quantidade de tags html num sítio web
    tags: h1, h2, h3, div, p, ul, ol
    inspiração: aula(!!!)
    '''
    def findTags(self, url):
        '''
        obter as quantidades de tags utilizados
        '''
        page = urllib2.urlopen(url)
        soup = BeautifulSoup(page)
        lista = ["h1", "h2", "h3", "div", "p", "ul", "ol"]
        tags = {}
        for tag in lista:
            tags[tag] = len(soup.findAll(tag))
            pass
        return tags
    # END OF findTags()
#END OF CLASS Soup


class HttpServer:
    '''
    servidor http na porta 8080
    '''
    def __init__(self):
        self.__PORT = 8080
        self.__Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
        self.__httpd = SocketServer.TCPServer(("", self.__PORT), self.__Handler)
        
    def start(self):
        '''
        iniciar o servidor
        '''
        print "serving at port", self.__PORT
        self.__httpd.serve_forever()
        pass
    #END OF start()

    def stop(self):
        '''
        parar o servidor
        '''
        self.__httpd.shutdown();
        print "server stopped"
        pass
    #END OF stop()
#ENDOF CLASS HttpServer


